package com.googlecode.groovy_toy_orm

import com.googlecode.groovy_toy_orm.internal.CodeBased

/**
 * @author: DavydovMD
 * Date: 04.04.13
 * Time: 18:45
 */
public class MapperUtil {
    @Singleton
    public static class Transformations {
    /*
     {Field f, Map map ->
            assert f.from.size()==1
            return [(f.name): map[f.from.last()]]  as Map
        }
    */

        public Closure _default() {
            return { Field f, Map map ->
                assert f.from.size() == 1
                return map[f.from.last()]
            }
        }

        public Closure codeBasedEnum(Class<? extends CodeBased> clazz) {
            return { Field f, Map map ->
                assert f.from.size() == 1
                int code = map[f.from.last()]
                def eVal = clazz.invokeMethod("fromCode", code)
                return eVal
            }
        }

        public Closure stringEnum(Class<? extends Enum> clazz) {
            return{ Field f, Map map ->
                assert f.from.size() == 1
                String code = map[f.from.last()]  as String
                def eVal = clazz.invokeMethod("valueOf", code)
                return eVal
            }
        }

        public Closure intToBool() {
            return{ Field f, Map map ->
                assert f.from.size() == 1
                String code = map[f.from.last()]  as String
                return code == 1
            }
        }

    }

    @Singleton
    public static class TransformationsBack {
     /*
    {Field f, def value ->
          (f.from.size() == 1) ? [(f.from.last()): value] as Map : [:]
      }
    */

        public Closure<Map> _default() {
            return { Field f, def value ->
                (f.from.size() == 1) ? [(f.from.last()): value] as Map : [:]
            }
        }

        public Closure codeBasedEnum(Class<? extends CodeBased> clazz) {

            return { Field f, def value ->
                //assert value.getClass() == clazz
                (f.from.size() == 1) ? [(f.from.last()): value.getCode() as int] as Map : [:]
            }
        }

        public Closure intToBool() {
            return { Field f, def value ->
                (f.from.size() == 1) ? [(f.from.last()): value? 1:0] as Map : [:]
            }
        }

        public Closure stringEnum(Class<? extends Enum> clazz) {
            return { Field f, def value ->
                assert value.getClass() == clazz
                (f.from.size() == 1) ? [(f.from.last()): value.toString()] as Map : [:] as Map
            }
        }
    }

    public static transform = Transformations.instance
    public static transformBack = TransformationsBack.instance


}
